#include "Utils.hpp"

Utils::Utils() {};

Utils::~Utils() {};

void Utils::drawRect( IplImage* img, int x1, int y1, int x2, int y2) {
   cvRectangle (
      img,
      cvPoint(x1,y1),
      cvPoint(x2,y2),
      cvScalar(0x11,0x11,0x11)    /* white */
   );
}

/*
void Utils::deformPic(IplImage* origImg,IplImage* destImg,CvRect box, int d, bool leftToRight, int interpolationMethod) {
	int middleLineX = box.x + box.width/2;
	int middleLineY = box.y + box.height/2;

	Parabola deformParab;
	if (leftToRight) {
		deformParab.setNewParabola(box.y, middleLineX, middleLineY, middleLineX+d, box.y+box.height, middleLineX);
	} else {
		deformParab.setNewParabola(box.y, middleLineX, middleLineY, middleLineX-d, box.y+box.height, middleLineX);
	}

	// Get the image data
	int height    = box.height;
	int width     = box.width;
	int step      = destImg->widthStep;
	int channels  = destImg->nChannels;
	uchar* origData      = (uchar *)origImg->imageData;
	uchar* destData      = (uchar *)destImg->imageData;

	// deforms the image
	for(int i=box.y;i<height+box.y;i++) {
		double xParab = deformParab.calc(i);
		double dTag =  abs(xParab - middleLineX);
		if (leftToRight) { //leftToRight
			for(int j=box.x;j<width+box.x;j++) {
				double ratio;
				if (leftToRight) {
					if (j<xParab) {
						ratio = 1.0 - (double)(xParab-j)/ (double)(xParab - box.x);
					} else {
						ratio = 1.0 - (double)(j-xParab)/ (double)(box.x + box.width - xParab);
					}
				} else {
					if (j<xParab) {
						ratio = 1.0 - (double)(xParab -j)/ (double)(middleLineXxParab - box.x);
					} else {
						ratio = 1.0 - (double)(j - xParab)/ (double)(box.x + box.width - xParab);
					}
				}

				for(int k=0;k<channels;k++) {
					double oldXdouble;
					if (leftToRight) {
						oldXdouble = abs ((double)j - ratio*dTag);
					} else {
						oldXdouble = abs ((double)j + ratio*dTag);
					}
					switch (interpolationMethod) {
						case 1: nearest(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
						case 2: biLinear(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
						case 3: biCubic(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
					}
				}
			}
		} else { //rightToLeft
			for(int j=box.width+box.x;j>box.x;j--) {
				double ratio;
				if (leftToRight) {
					if (j<xParab) {
						ratio = 1.0 - (double)(xParab-j)/ (double)(xParab - box.x);
					} else {
						ratio = 1.0 - (double)(j-xParab)/ (double)(box.x + box.width - xParab);
					}
				} else {
					if (j<xParab) {
						ratio = 1.0 - (double)(xParab -j)/ (double)(middleLineXxParab - box.x);
					} else {
						ratio = 1.0 - (double)(j - xParab)/ (double)(box.x + box.width - xParab);
					}
				}
				for(int k=0;k<channels;k++) {
					double oldXdouble;
					if (leftToRight) {
						oldXdouble =(double)j - ratio*dTag;
					} else {
						oldXdouble =(double)j + ratio*dTag;
					}
					switch (interpolationMethod) {
						case 1: nearest(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
						case 2: biLinear(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
						case 3: biCubic(oldXdouble,origData,destData,i,step,j,channels,k);
								break;
					}
				}
			}
		}
	}

}

void Utils::nearest(double oldXdouble,uchar* origData, uchar* destData, int i, int step, int j, int channels, int k  ) {
	//nearest
	int oldX = int(oldXdouble + 0.5);
	//bilinear
	destData[i*step+j*channels+k] = origData[i*step+oldX*channels+k];
}

void Utils::biLinear(double oldXdouble,uchar* origData, uchar* destData, int i, int step, int j, int channels, int k ) {
	int leftX = (int)oldXdouble;
	int rightX = leftX + 1;
	//0<=t<=1
	double t = oldXdouble - leftX;

	destData[i*step+j*channels+k] = (1-t)*origData[i*step+leftX*channels+k] + t*origData[i*step+rightX*channels+k];
}

void Utils::biCubic(double oldXdouble,uchar* origData, uchar* destData, int i, int step, int j, int channels, int k ) {
	double pos [4];
	double val [4];

	int leftX = (int)oldXdouble;
	int leftY = origData[i*step+leftX*channels+k];

	int leftLeftX = leftX-1;
	int leftLeftY = origData[i*step+leftLeftX*channels+k];

	int rightX = leftX + 1;
	int rightY = origData[i*step+rightX*channels+k];

	int rightRightX = rightX + 1;
	int rightRightY = origData[i*step+rightRightX*channels+k];

	pos[0] = leftLeftX; val[0] = leftLeftY;
	pos[1] = leftX; val[1] = leftY;
	pos[2] = rightX; val[2] = rightY;
	pos[3] = rightRightX; val[3] = rightRightY;


	destData[i*step+j*channels+k] = (int)lagrangeInterpolatingPolynomial(pos,val,4,oldXdouble);
}


double Utils::lagrangeInterpolatingPolynomial (double pos[], double val[], int degree, double desiredPos)  {
   double retVal = 0;

   for (int i = 0; i < degree; ++i) {
      double weight = 1;

      for (int j = 0; j < degree; ++j) {
         // The i-th term has to be skipped
         if (j != i) {
            weight *= (desiredPos - pos[j]) / (pos[i] - pos[j]);
         }
      }
      retVal += weight * val[i];
   }

   return retVal;
}

*/
